package org.onvivals.app.modules.pms.controller;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onvivals.app.modules.auth.util.SaTokenUtil;
import org.onvivals.app.modules.ums.param.RechargeRoleParam;
import org.onvivals.app.weixin.service.WeixinPayService;
import org.onvivals.common.enums.AppFromEnum;
import org.onvivals.common.enums.BillDetailEnum;
import org.onvivals.common.exception.BusinessException;
import org.onvivals.common.param.PageParam;
import org.onvivals.common.web.PageResult;
import org.onvivals.common.web.Result;
import org.onvivals.module.iot.entity.IotDevice;
import org.onvivals.module.iot.service.IIotDeviceService;
import org.onvivals.module.pms.entity.PmsHistory;
import org.onvivals.module.pms.entity.PmsRole;
import org.onvivals.module.pms.entity.PmsRoleIndividuality;
import org.onvivals.module.pms.param.PmsRoleParam;
import org.onvivals.module.pms.service.IPmsHistoryService;
import org.onvivals.module.pms.service.IPmsRoleIndividualityService;
import org.onvivals.module.pms.service.IPmsRoleService;
import org.onvivals.module.ums.entity.UmsUser;
import org.onvivals.module.ums.entity.UmsUserRole;
import org.onvivals.module.ums.service.IUmsUserRechargeService;
import org.onvivals.module.ums.service.IUmsUserRoleService;
import org.onvivals.module.ums.service.IUmsUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Tag(name = "小程序:角色")
@RequestMapping("/role")
public class PmsRoleController {

	private final IPmsRoleService roleService;

	private final IPmsRoleIndividualityService pmsRoleIndividualityService;

	private final IUmsUserRechargeService userRechargeService;

	private final IUmsUserService umsUserService;

	private final WeixinPayService wxPayService;

	private final IUmsUserRoleService userRoleService;

	private final IPmsHistoryService pmsHistoryService;

	private final IIotDeviceService deviceService;

	@Operation(summary = "分页查询全部角色")
	@GetMapping("/page")
	public Result<PageResult<PmsRole>> page(PmsRoleParam param) {
		Long userId = SaTokenUtil.getUserId();
		PageParam<PmsRole, PmsRoleParam> page = new PageParam<>(param);
		page.setDefaultOrder("sort desc");
		QueryWrapper<PmsRole> wrapper = page.getWrapper();
		wrapper.eq("is_system", 1);
		List<PmsRole> roleList = roleService.list(wrapper);
		roleList.forEach(pmsRole -> {
			UmsUserRole userRole = userRoleService.getOne(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getRoleId, pmsRole.getId()).eq(UmsUserRole::getUserId, userId));
			if (userRole != null) {
				pmsRole.setIsPay(Boolean.TRUE);
			} else {
				pmsRole.setIsPay(Boolean.FALSE);
			}
		});
		PageResult<PmsRole> pageResult = new PageResult<>(roleList, (long) roleList.size());
		return Result.OK("查询成功", pageResult);
	}

	@Operation(summary = "查询全部角色")
	@GetMapping("/list")
	public Result<List<PmsRole>> list(PmsRoleParam param) {
		Long userId = SaTokenUtil.getUserId();
		PageParam<PmsRole, PmsRoleParam> page = new PageParam<>(param);
		page.setDefaultOrder("sort desc");
		QueryWrapper<PmsRole> wrapper = page.getWrapper();
		wrapper.eq("is_system", 1);
		List<PmsRole> roleList = roleService.list(wrapper);
		roleList.forEach(pmsRole -> {
			UmsUserRole userRole = userRoleService.getOne(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getRoleId, pmsRole.getId()).eq(UmsUserRole::getUserId, userId));
			if (userRole != null) {
				pmsRole.setIsPay(Boolean.TRUE);
				pmsRole.setNickName(userRole.getRoleName());
			} else {
				pmsRole.setIsPay(Boolean.FALSE);
			}
		});
		return Result.OK("查询成功", roleList);
	}

	@Operation(summary = "查询个人角色")
	@GetMapping("/my/list")
	public Result<List<PmsRole>> Mylist(PmsRoleParam param) {
		Long userId = SaTokenUtil.getUserId();
		PageParam<PmsRole, PmsRoleParam> page = new PageParam<>(param);
		page.setDefaultOrder("sort desc");
		QueryWrapper<PmsRole> wrapper = page.getWrapper();
		wrapper.eq("uid", userId);
		List<PmsRole> roleList = roleService.list(wrapper);
		return Result.OK("查询成功", roleList);
	}

	@Operation(summary = "根据id查询角色")
	@GetMapping("/{id}")
	public Result<PmsRole> get(@PathVariable("id") Long id) {
		Long userId = SaTokenUtil.getUserId();
		PmsRole pmsRole = roleService.getById(id);
		if (pmsRole != null) {
			List<PmsRoleIndividuality> list = pmsRoleIndividualityService.list(Wrappers.<PmsRoleIndividuality>lambdaQuery().eq(PmsRoleIndividuality::getRoleId, id));
			pmsRole.setIndividualityList(list);
			UmsUserRole userRole = userRoleService.getOne(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getRoleId, id).eq(UmsUserRole::getUserId, userId));
			if (userRole != null) {
				pmsRole.setIsPay(Boolean.TRUE);
				pmsRole.setNickName(userRole.getRoleName());
			} else {
				pmsRole.setIsPay(Boolean.FALSE);
			}
		}
		return Result.OK("查询成功", pmsRole);
	}

	/**
	 * 角色购买
	 */
	@PostMapping("/pay")
	@Operation(summary = "角色购买")
	public Result<Map<String, Object>> vipPay(@Valid @RequestBody RechargeRoleParam param) {
		UmsUser pmsMember = SaTokenUtil.getUser();
		Map<String, Object> map = new LinkedHashMap<>();
		map.put("type", param.getFrom());
		PmsRole role = roleService.getById(param.getRecharId());
		if (role == null) {
			throw new BusinessException("充值方案不存在");
		}
		String price = Convert.toStr(role.getPrice());
		String name = role.getName();
		String orderSn = userRechargeService.addRoleRecharge(pmsMember, price, name, "role", role.getId());
		if (AppFromEnum.ROUNTINE.getValue().equals(param.getFrom())) {
			WxPayMpOrderResult wxPayMpOrderResult = (WxPayMpOrderResult) wxPayService
					.unifyPay(orderSn, param.getFrom(), BillDetailEnum.TYPE_14.getValue(), "角色购买");
			Map<String, String> jsConfig = new HashMap<>();
			jsConfig.put("timeStamp", wxPayMpOrderResult.getTimeStamp());
			jsConfig.put("appId", wxPayMpOrderResult.getAppId());
			jsConfig.put("paySign", wxPayMpOrderResult.getPaySign());
			jsConfig.put("nonceStr", wxPayMpOrderResult.getNonceStr());
			jsConfig.put("package", wxPayMpOrderResult.getPackageValue());
			jsConfig.put("signType", wxPayMpOrderResult.getSignType());
			map.put("data", jsConfig);
		}
		return Result.OK(map);
	}

	/**
	 * 修改角色名称
	 */
	@Operation(summary = "修改角色名称")
	@PostMapping
	public Result<Boolean> update(@Valid @RequestBody UmsUserRole role) {
		Long userId = SaTokenUtil.getUserId();
		UmsUserRole userRole = userRoleService.getOne(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getUserId, userId).eq(UmsUserRole::getRoleId, role.getRoleId()));
		if (userRole == null) {
			throw new BusinessException("用户角色不存在");
		}
		userRole.setRoleName(role.getRoleName());
		UpdateWrapper<UmsUserRole> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("user_id", userId).eq("role_id", role.getRoleId());
		UmsUserRole user = new UmsUserRole();
		user.setRoleName(role.getRoleName());
		userRoleService.update(user, updateWrapper);

		List<IotDevice> deviceList = deviceService.list(Wrappers.<IotDevice>lambdaQuery().eq(IotDevice::getUserId, userId));
		List<String> deviceNumList = deviceList.stream().map(IotDevice::getSerialNumber).collect(Collectors.toList());
		pmsHistoryService.remove(Wrappers.<PmsHistory>lambdaQuery().in(PmsHistory::getDeviceId, deviceNumList));
		return Result.OK("修改角色名称成功");
	}

	/**
	 * 解锁角色
	 */
	@Operation(summary = "解锁角色")
	@GetMapping("/unlock/{roleId}")
	public Result<?> delete(@PathVariable("roleId") Long roleId) {
		Long userId = SaTokenUtil.getUserId();
		UmsUserRole userRole = userRoleService.getOne(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getUserId, userId).eq(UmsUserRole::getRoleId, roleId));
		if (userRole == null) {
			PmsRole pmsRole = roleService.getById(roleId);
			if (pmsRole != null) {
				BigDecimal price = pmsRole.getPrice();
				if (Convert.toBigDecimal(price).compareTo(BigDecimal.ZERO) == 0) {
					userRoleService.remove(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getUserId, userId).eq(UmsUserRole::getRoleId, pmsRole.getId()));
					UmsUserRole umsUserRole = new UmsUserRole();
					umsUserRole.setUserId(userId);
					umsUserRole.setRoleId(pmsRole.getId());
					userRoleService.save(umsUserRole);
					return Result.OK("解锁成功", umsUserRole);
				}
			}
		} else {
			return Result.OK("已存在角色");
		}

		return Result.error("解锁失败");
	}

	/**
	 * 查询当前用户的角色数量
	 */
	@Operation(summary = "查询当前用户的角色数量")
	@GetMapping("/checkRole")
	public Result<?> count() {
		Long userId = SaTokenUtil.getUserId();
		long count = roleService.count(Wrappers.<PmsRole>lambdaQuery().eq(PmsRole::getUid, userId));
		UmsUser umsUser = umsUserService.getById(userId);
		Integer roleNum = umsUser.getRoleNum();
		BigDecimal finalNum = NumberUtil.sub(Convert.toInt(roleNum), Convert.toInt(count));
		if (finalNum.compareTo(BigDecimal.ZERO) < 0) {
			return Result.error("角色数量超出限制");
		}
		return Result.OK("查询成功", finalNum.intValue());
	}

	@Operation(summary = "添加角色")
	@PostMapping("/save")
	public Result<?> save(@RequestBody PmsRole pmsRole) {
		Long userId = SaTokenUtil.getUserId();
		long count = roleService.count(Wrappers.<PmsRole>lambdaQuery().eq(PmsRole::getUid, userId));
		UmsUser umsUser = umsUserService.getById(userId);
		Integer roleNum = umsUser.getRoleNum();
		if (count > roleNum) {
			return Result.error("角色数量超出限制");
		}
		pmsRole.setUid(userId);
		pmsRole.setIsSystem(false);
		pmsRole.setLlmId(9L);
		pmsRole.setTtsId(11L);
		pmsRole.setIsDefault(false);
		pmsRole.setPrice(BigDecimal.ZERO);
		pmsRole.setOriginalPrice(BigDecimal.ZERO);
		pmsRole.setMaxMessageCount(10);
		pmsRole.setSort(0);
		if (roleService.save(pmsRole)) {
			String serialNumber = pmsRole.getSerialNumber();
			System.out.println(serialNumber);
			IotDevice iotDevice = deviceService.selectDeviceBySerialNumber(serialNumber);
			iotDevice.setRoleId(pmsRole.getId());
			iotDevice.setIndividualityId(null);
			deviceService.updateById(iotDevice);
			return Result.OK("添加成功");

		}
		return Result.error("添加失败");
	}

	@Operation(summary = "修改角色")
	@PutMapping("/update")
	public Result<?> update(@RequestBody PmsRole pmsRole) {
		if (roleService.updateById(pmsRole)) {
			String serialNumber = pmsRole.getSerialNumber();
			IotDevice iotDevice = deviceService.selectDeviceBySerialNumber(serialNumber);
			iotDevice.setRoleId(pmsRole.getId());
			iotDevice.setIndividualityId(null);
			deviceService.updateById(iotDevice);
			return Result.OK("修改成功");
		}
		return Result.error("修改失败");
	}


}
